#!/usr/bin/env node
/**
 * Playwright MCP 服务器
 * 基于官方 Programmatic usage 实现
 */

import http from 'http';
import { createConnection } from '@playwright/mcp';
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';

class PlaywrightMCPServer {
  constructor(port = 3000) {
    this.port = port;
    this.server = null;
    this.connections = new Map();
  }

  async start() {
    this.server = http.createServer(async (req, res) => {
      // 设置 CORS 头
      res.setHeader('Access-Control-Allow-Origin', '*');
      res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
      res.setHeader('Access-Control-Allow-Headers', 'Content-Type');

      if (req.method === 'OPTIONS') {
        res.writeHead(200);
        res.end();
        return;
      }

      if (req.url === '/health') {
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ status: 'healthy', timestamp: new Date().toISOString() }));
        return;
      }

      if (req.url === '/messages') {
        try {
          console.log('🔗 新的 MCP 连接请求');
          
          // 创建 Playwright MCP 连接
          const connection = await createConnection({
            browser: {
              launchOptions: {
                headless: false, // 开发时设为 false，生产时设为 true
                args: [
                  '--no-sandbox',
                  '--disable-setuid-sandbox',
                  '--disable-blink-features=AutomationControlled'
                ]
              }
            }
          });

          // 创建 SSE 传输
          const transport = new SSEServerTransport('/messages', res);
          
          // 连接
          await connection.connect(transport);
          
          // 保存连接引用
          const connectionId = Date.now().toString();
          this.connections.set(connectionId, { connection, transport });
          
          console.log(`✅ MCP 连接建立成功: ${connectionId}`);
          
          // 连接关闭时清理
          req.on('close', () => {
            console.log(`🔌 连接关闭: ${connectionId}`);
            this.connections.delete(connectionId);
          });

        } catch (error) {
          console.error('❌ MCP 连接失败:', error);
          res.writeHead(500, { 'Content-Type': 'application/json' });
          res.end(JSON.stringify({ error: error.message }));
        }
      } else {
        res.writeHead(404, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ error: 'Not Found' }));
      }
    });

    return new Promise((resolve, reject) => {
      this.server.listen(this.port, (error) => {
        if (error) {
          reject(error);
        } else {
          console.log(`🚀 Playwright MCP 服务器启动成功`);
          console.log(`📡 服务地址: http://localhost:${this.port}`);
          console.log(`🔗 MCP 端点: http://localhost:${this.port}/messages`);
          console.log(`💓 健康检查: http://localhost:${this.port}/health`);
          resolve();
        }
      });
    });
  }

  async stop() {
    if (this.server) {
      // 关闭所有连接
      for (const [id, { connection }] of this.connections) {
        try {
          await connection.close();
          console.log(`🔌 关闭连接: ${id}`);
        } catch (error) {
          console.error(`❌ 关闭连接失败 ${id}:`, error);
        }
      }
      
      this.connections.clear();
      
      return new Promise((resolve) => {
        this.server.close(() => {
          console.log('🛑 Playwright MCP 服务器已停止');
          resolve();
        });
      });
    }
  }
}

// 启动服务器
const server = new PlaywrightMCPServer(3000);

async function main() {
  try {
    await server.start();
    
    // 优雅关闭处理
    process.on('SIGINT', async () => {
      console.log('\n🛑 收到停止信号，正在关闭服务器...');
      await server.stop();
      process.exit(0);
    });
    
    process.on('SIGTERM', async () => {
      console.log('\n🛑 收到终止信号，正在关闭服务器...');
      await server.stop();
      process.exit(0);
    });
    
  } catch (error) {
    console.error('❌ 服务器启动失败:', error);
    process.exit(1);
  }
}

// 错误处理
process.on('unhandledRejection', (reason, promise) => {
  console.error('❌ 未处理的 Promise 拒绝:', reason);
});

process.on('uncaughtException', (error) => {
  console.error('❌ 未捕获的异常:', error);
  process.exit(1);
});

main();
